/*!  \file  SteV.cpp
 *	  \brief  
 * 
 *   \details   details
 *   \author    Yordan Madzhunkov German Research School for Simulation Sciences GmbH
 *   \version   1.0
 *   \date      07/07/2013 10:26:47 AM
 *   \copyright GNU Public License.
 */

#include "SteV.h"
#include "Matrix.h"
#include "setThreads.h"
extern "C" {
void dstev_(
const char   * jobz, 
const int    * n, 
double * d, 
double * e, 
double * z,
const int  * ldz,
double * work, // size = 2N - 2
int    * info);

}
SteV::SteV(): TriEigen("Lapack dstev") {	
	setCompileTime(__DATE__, __TIME__); 
	canBeParallel = true;
}
bool SteV::setNumberOfThreads(int nThreads_) {	
	assert(canBeParallel);
	SET_NUM_THREADS(nThreads_);
	nThreads = nThreads;
	return true;
}
void  SteV::compute(const Matrix & T, Matrix & Sigma, Matrix & Q ){
	reset();
	if (!T.isTriDiagonal()) return;
	char jobz = 'V';
	int n = T.cols(), info = -1, lwork = min(3 * n ,1);
	double *    e = NULL;
	double * work = NULL;
	double *    d = NULL;
	double *    q = NULL;
	allocate(e, n); allocate(work, lwork);
	d    = Sigma.getModData();
	q    = Q.getModData();
	memcpy(d, T.getData()    ,    n * sizeof(*d));
	memcpy(e, T.getOffDiagonal(), (n-1)* sizeof(*d));
	int ldq = Q.lda();	Q.makeColMajor(); Q.makeOrthogonal();
	dstev_(&jobz, &n, d, e, q, &ldq, work, &info);
	success &= info == 0;
	delocate(e); delocate(work);
};
//REGISTER(SteV);
